package java学习.第11章_常用类和基础API;

import org.junit.Test;

/**
 * 关于String
 * 底层使用 char[]存储  jdk 9开始
 * String：       不可变的字符序列   final char[]       jdk1.0
 * StringBuffer： 可变的字符序列           char[]      jdk 1.0  线程安全     效率低
 * StringBuilder：可变的字符序列           char[]      jdk 5.0  线程不安全   效率高
 * <p>
 * 可以直接指定长度
 * 扩容机制：二倍+2 或 等于原长度+添加的长度
 */
public class D_可变字符序列 {

    @Test
    public void new创建() {
        //相当于new char[0]
        String str0 = new String();
        //相当于new char[]{'a','b','c'};
        String str1 = new String("abc");

        //相当于char[] value=new char[16]//默认16个
        StringBuilder sbf0 = new StringBuilder();
        System.out.println(sbf0.length());//0   //重写了
        sbf0.append('a');//value[0] = 'a';
        sbf0.append('b');//value[1] = 'b';
        sbf0.append('c');//value[2] = 'c';
        /**
         * 扩容
         * 默认情况下(value.length << 1) + 2;  扩到原来的两倍+2
         * if (newCapacity - minCapacity < 0) {
         *     newCapacity = minCapacity;
         * }//如果还是不行  新加的字符太长了   扩到添加的字符那麽多
         *
         */
        //相当于new char["abc".length()+16];
        StringBuilder sbf1 = new StringBuilder("abc");
        sbf1.append("5844444444444444444444444444444444444444444444444444444");
        System.out.println(sbf0 == sbf1);//false
        sbf1.setCharAt(0, 'm');
        System.out.println(sbf0 + "***" + sbf1);//abc***mbc
    }

    /**
     * StringBuffer append(xxx): 提供了很多的append()方法，用于进行字符串拼接
     * StringBuffer delete(int start, int end): 删除指定位置的内容
     * StringBuffer replace(int start, int end, String str): 把[start, end)位置替换为str
     * StringBuffer insert(int offset, xxx): 在指定位置插xxx
     * StringBuffer reverse() :把当前字符序列逆转
     * public int index0f(String str)
     * public String substring(int start, int end)
     * public int length()
     * public char charAt(int n )
     * public void setCharAt(int n , char ch)
     */
    @Test
    public void 一部分方法() {

        StringBuffer sbf = new StringBuffer();
        System.out.println("--------append()---------------------");
        sbf.append("abc");
        sbf.append(1);//添加
        System.out.println(sbf);//abc1
        System.out.println("--------delete()---------------------");
        sbf.delete(2, 3);//删除  [2,3)
        System.out.println(sbf);//ab1
        System.out.println("--------replace()---------------------");
        //如果end大于length相当于把后面的 end=length
        // 但是start 也就是第一个数字 必须>=0否则报错
        sbf.replace(2, 5646, "cdef");//修改
        System.out.println(sbf);//abcdef
        System.out.println("--------insert()---------------------");
        sbf.insert(1, "A");//在第一个字符后插入
        System.out.println(sbf);//aAbcdef
        System.out.println("--------length()---------------------");
        System.out.println(sbf.length());//7 返回实打实存储了几个字符
        sbf.setLength(8);
        System.out.println((int)sbf.charAt(7));// ASCII  :  0    空字符：null
        System.out.println((int)' ');// ASCII  :  32
        sbf.setLength(7);
        System.out.println(sbf);//7 返回实打实存储了几个字符
        System.out.println("--------reverse()---------------------");
        sbf.reverse();//反转
        System.out.println(sbf);//fedcbAa
        System.out.println("--------setCharAt()---------------------");
        sbf.setCharAt(0, 'M');//将下标为0的字符改成M
        System.out.println(sbf);//MedcbAa
        System.out.println("--------substring()---------------------");
        String sbf1 = sbf.substring(0, 1);//返回下标为0到下标不为1的字符串 [0,1)
        System.out.println(sbf1);//M
    }


    @Test
    public void 空指针情况() {
        String str = null;//new String() b.length()==0
        StringBuffer sb = new StringBuffer();
        /**
         *         int c = count;
         *         ensureCapacityInternal(c + 4);
         *         final char[] value = this.value;
         *         value[c++] = 'n';
         *         value[c++] = 'u';
         *         value[c++] = 'l';
         *         value[c++] = 'l';
         *         count = c;
         *         return this;
         */
        System.out.println(sb.length());//0
        System.out.println(sb);//
        sb.append(str);
        System.out.println(sb.length());//4
        System.out.println(sb);//null

        //异常java.lang.NullPointerException
        StringBuffer sb1 = new StringBuffer(str);
    }

    @Test
    public void 执行时间() {
        /**
         * 执行时间
         * String>StringBuffer>StringBuilder
         */
        //初始数据
        long startTime = 0L;
        long endTime = 0L;
        String str = "";
        StringBuffer buffer = new StringBuffer("");
        StringBuilder builder = new StringBuilder("");
        startTime = System.currentTimeMillis();
        for (int i = 0; i < 20000; i++) {
            buffer.append(String.valueOf(i));
        }
        endTime = System.currentTimeMillis();
        System.out.println("StringBuffer执行时间" + (endTime - startTime));

        startTime = System.currentTimeMillis();
        for (int i = 0; i < 20000; i++) {
            builder.append(String.valueOf(i));
        }
        endTime = System.currentTimeMillis();
        System.out.println("StringBuilder" + (endTime - startTime));

        startTime = System.currentTimeMillis();
        for (int i = 0; i < 20000; i++) {
            str = str + i;
        }
        endTime = System.currentTimeMillis();
        System.out.println("String执行时间" + (endTime - startTime));
    }


}
